package br.com.dataphonebr;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.TimePicker;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.Spinner;
import android.widget.TextView;
import br.com.dataphonebr.adapter.AdministratorListAdapter;
import br.com.dataphonebr.entity.Atividade;
import br.com.dataphonebr.entity.Grupo;
import br.com.dataphonebr.enumerator.PeriodoNotificacao;
import br.com.dataphonebr.enumerator.StatusAtividade;
import br.com.dataphonebr.selectListener.GrupoSelectedListener;
import br.com.dataphonebr.service.AtividadeService;
import br.com.dataphonebr.service.GrupoService;
import br.com.dataphonebr.util.Util;

public class AdministratorListActivity extends GenericActivity<Atividade> implements OnChildClickListener {
	
	public enum ProcessoItem{
		EXCLUIR,
		FINALIZAR,
		CANCELAR,
		ADIAR,
		RENOVAR,
		REATIVAR;
	}
	
	private Calendar dataAdiamento;
	private Calendar horaAdiamento;
	private Button finalizeAppointmentBtn;
	private Button cancelAppointmentBtn;
	private EditText notasFinalizacao;
	private ProcessoItem processo = null;
	private TextView data;
	private ExpandableListView lista;
	private AtividadeService atividadeService;
	private GrupoService grupoService;
	private Spinner grupoSpin;
	private CheckBox desativarRepeticao;
	private Grupo grupo;
	private GrupoSelectedListener grupoListener = new GrupoSelectedListener(this);
	private AdministratorListAdapter admListener = new AdministratorListAdapter(this);
	protected AlertDialog alertDialogConcluida;
	protected TimePickerDialog postponeTimePicker;
//	protected AlertDialog alertDialogOk;
	private Dialog notesDialog;
	private boolean cancelado;
	
	public AdministratorListActivity() {
		super(Atividade.class);
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_administrator_list);
		getActionBar().setDisplayHomeAsUpEnabled(true);
		init();
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
	    inflater.inflate(R.menu.administrator_list, menu);
	    return true;
	} 	
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		showProgressBar(AdministratorListActivity.this, null);
		switch (item.getItemId()) {
	    case R.id.addAdmActionMenu:
			List<Grupo> grupos = grupoService.selectAll();
			if (grupos != null && !grupos.isEmpty()){
				Intent intent = new Intent(AdministratorListActivity.this, AppointmentActivity.class);
				intent.putExtra(Util.COMING_FROM, R.layout.activity_administrator_list);
				startActivity(intent);
				finish();
				return true;
	    	} 
			util.showToastMessageLong(getString(R.string.msg_no_group_registered), this);
			return false;
	    case R.id.searchAdmActionMenu:
			openView(AdministratorListActivity.this, SearchAdmActivity.class, false);
	    	return true;
	    case android.R.id.home:
	    	Intent upIntent = new Intent(this, DashboardActivity.class);
            upIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(upIntent);	    	
            finish();
	    	return true;
	    default:
	        return super.onOptionsItemSelected(item);
	    }
	}
	
	@Override
	public void init(){
		atividadeService = new AtividadeService(this);
		grupoService = new GrupoService(this);
		super.init();
	}

	@Override
	public void prepareComponents() {
		grupoSpin =  (Spinner) findViewById(R.id.grupoAdmSpinnerId);
		grupoSpin.setOnItemSelectedListener(onItemSelectedGroup);
		lista = (ExpandableListView) findViewById(R.id.admListId);
		lista.setOnItemLongClickListener(onLongClick);
		data = (TextView) findViewById(R.id.dateTimeTextViewAdmId);
		alertDialog = super.createDialog(getString(R.string.optionsLabel), onClickNaoConcluidas, getOptionsAppointmentMenu());
		alertDialogConcluida = super.createDialog(getString(R.string.optionsLabel), onClickConcluidas, getString(R.string.alert_display_adm), getString(R.string.alert_duplicate_adm), getString(R.string.alert_remove_adm));
		alertYesNo = super.createDialogYesNo(onClickNaoConcluidas);
		notesDialog = atividadeService.criarPopupFinalizacao(this, getInstance());
		if (notesDialog != null){
			desativarRepeticao = (CheckBox) notesDialog.findViewById(R.id.checkBoxCancelarAdm);
			notasFinalizacao = (EditText)notesDialog.findViewById(R.id.notasFinalizacaoAdm);
			finalizeAppointmentBtn = (Button) notesDialog.findViewById(R.id.finalizeBtnAdm);
			finalizeAppointmentBtn.setOnClickListener(finalizeClick);
			cancelAppointmentBtn = (Button) notesDialog.findViewById(R.id.cancelBtnAdm);
			cancelAppointmentBtn.setOnClickListener(finalizeClick);
		}
		super.prepareComponents();
	}
	
	@Override
	public void prepareList() {
		grupoListener.createAdapter(grupoService.selectAll(), grupoSpin, true);
		lista.setOnChildClickListener(this);
		this.pesquisar(grupo);
		data.setText(util.dateToStringFull(new Date(), this));
		super.prepareList();
	}
	
	private List<Atividade> getAtividadesAdm(Grupo grupo){
		this.showProgressBar(AdministratorListActivity.this, null);
		List<Atividade> atividadesAdm = atividadeService.selectAtividadesAdmPorGrupo(grupo);
		return atividadesAdm;
	}
	
	  AdapterView.OnItemSelectedListener onItemSelectedGroup = new AdapterView.OnItemSelectedListener() {
		@Override
		public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
			grupo = (Grupo) parent.getItemAtPosition(pos);
			pesquisar(grupo);
		}

		@Override
		public void onNothingSelected(AdapterView<?> arg0) {
		}
	  };
	
	private void pesquisar(Grupo grupo){
		this.showProgressBar(AdministratorListActivity.this, null);
		admListener.createAdapter(getAtividadesAdm(grupo), lista);
	}
	
	public void refresh(View v){
		atividadeService.generatePDF(getAtividadesAdm(grupo));
		pesquisar(grupo);
	}
	
	View.OnClickListener finalizeClick = new View.OnClickListener() {
	    public void onClick(View v) {
	    	switch (v.getId()){
		    	case R.id.finalizeBtnAdm : {
		    		String mensagem = "";
		    		if (processo.equals(ProcessoItem.FINALIZAR)){
		    			mensagem = getString(R.string.finalize_message, getInstance().getTitulo()+" ("+getInstance().getGrupo().getNome()+")");
		    			if (desativarRepeticao != null && desativarRepeticao.isChecked()){
		    				mensagem = getString(R.string.finalize_and_disable_appointment, getInstance().getTitulo());
		    			}
		    			if (admListener.atividadeEmAndamentoValida(getInstance())){
		    				mensagem = getString(R.string.finalize_and_disable_appointment_in_progress, mensagem);
		    			}
		    		}  
		    		if (processo.equals(ProcessoItem.CANCELAR)){
						mensagem = getString(R.string.cancel_message, getInstance().getTitulo()+" ("+getInstance().getGrupo().getNome()+")");
						if (admListener.atividadeEmAndamentoValida(getInstance())){
							mensagem = getString(R.string.cancel_and_disable_appointment_in_progress, mensagem);
						}
		    		}
		    		if (mensagem != null && !mensagem.isEmpty()){
		    			alertYesNo.setMessage(mensagem);
		    			alertYesNo.show();
		    		}
		    	}
		    	break;
		    	case R.id.cancelBtnAdm : {
		    		notesDialog.dismiss();
		    	}
		    	break;
	    	}
	    }
	  };

	@Override
	public boolean onChildClick(ExpandableListView expList, View view, int groupPosition, int childPosition, long id) {
		setInstance((Atividade)admListener.getChild(groupPosition, childPosition));
		if (getInstance().getStatus().equals(StatusAtividade.CONCLUIDA)){
			alertDialogConcluida.setCanceledOnTouchOutside(true);
			alertDialogConcluida.show();
		} else {
			if ((getInstance().getDataIni() != null || getInstance().getHoraIni() != null) && getInstance().getDataFim() == null){
				alertDialog = super.createDialog(getString(R.string.optionsLabel), onClickNaoConcluidas, getOptionsPostponeAppointmentMenu());
			} else
				alertDialog = super.createDialog(getString(R.string.optionsLabel), onClickNaoConcluidas, getOptionsAppointmentMenu());
			alertDialog.setCanceledOnTouchOutside(true);
			alertDialog.show();
		}
		return true;
	}

	OnClickListener onClickNaoConcluidas = new OnClickListener() {
		
		@Override
		public void onClick(DialogInterface dialog, int which) {
			switch (which) {
			case 0:
				showProgressBar(AdministratorListActivity.this, null);
				loadInstance(AppointmentActivity.class, atividadeService.getColumnHack(), getInstance().getCodigo(), true, R.layout.activity_administrator_list);
				break;
			case 1:
				showProgressBar(AdministratorListActivity.this, null);
				duplicate(AppointmentActivity.class, atividadeService.getColumnHack(), getInstance().getCodigo(), R.layout.activity_administrator_list);
				break;
			case 2:
				if (getInstance() != null && getInstance().getCodigo() != null){
					processo = ProcessoItem.EXCLUIR;
					alertYesNo.setMessage(getString(R.string.remove_appointment_message, getInstance().getTitulo()+" ("+getInstance().getGrupo().getNome()+")"));
					alertYesNo.show();
				}
				break;
			case 3:
				if (getInstance() != null && getInstance().getCodigo() != null){
					processo = ProcessoItem.CANCELAR;
					TextView titulo = (TextView)notesDialog.findViewById(R.id.tituloPopupNotesAdm);
					titulo.setText(getString(R.string.notes_popup_cancel_adm));
					desativarRepeticao.setVisibility(View.GONE);
					notasFinalizacao.setText("");
					notesDialog.show();
				}
				break;
			case 4:
				if (getInstance() != null && getInstance().getCodigo() != null){
					processo = ProcessoItem.FINALIZAR;
					TextView titulo = (TextView)notesDialog.findViewById(R.id.tituloPopupNotesAdm);
					titulo.setText(getString(R.string.notes_popup_finalize_adm));
					if (getInstance().getPeriodoNotificacao().equals(PeriodoNotificacao.NENHUM)){
						desativarRepeticao.setVisibility(View.GONE);
					} else {
						desativarRepeticao.setVisibility(View.VISIBLE);
						desativarRepeticao.setChecked(false);
					}
					notasFinalizacao.setText("");
					notesDialog.show();
				}
				break;
			case 5:
				if (getInstance() != null && getInstance().getCodigo() != null){
					processo = ProcessoItem.ADIAR;
					cancelado = false;
					Calendar calendar = Calendar.getInstance();
					String titulo;
					if (getInstance().getDataAviso().before(new Date())){
						calendar.setTime(new Date());
						titulo = getString(R.string.current_date_title);
					} else {
						calendar.setTime(getInstance().getDataAviso());
						titulo = getString(R.string.current_alert_date_title);
					}
					DatePickerDialog datePicker = new DatePickerDialog(AdministratorListActivity.this, onDateListener
																		, calendar.get(Calendar.YEAR)
																		, calendar.get(Calendar.MONTH)
																		, calendar.get(Calendar.DAY_OF_MONTH));
					
					datePicker.setButton(DatePickerDialog.BUTTON_NEGATIVE, getString(R.string.cancel), cancelClick);
					datePicker.setCanceledOnTouchOutside(false);
					datePicker.setMessage(titulo);
		    		datePicker.show();
				}
//				if (getInstance() != null && getInstance().getCodigo() != null){
//					processo = ProcessoItem.RENOVAR;
//					alertYesNo.setMessage("Ao renovar a atividade, o hist�rico de finaliza��o n�o ser� guardado. Deseja realmente renovar a atividade "+getInstance().getTitulo()+"? ");
//					alertYesNo.show();
//				}
				break;
			case DialogInterface.BUTTON_POSITIVE:
//				TODO: Incluir regras de negocio de exclus�o.
				if (processo != null){
					showProgressBar(AdministratorListActivity.this, null);
					if (processo.equals(ProcessoItem.EXCLUIR)){
						atividadeService.delete(getInstance().getCodigo());
					}
					if (processo.equals(ProcessoItem.FINALIZAR)){
						getInstance().setNotasFinalizacao(notasFinalizacao.getText().toString());
						getInstance().setDesativarRepeticao(desativarRepeticao.isChecked());
						atividadeService.finalizar(getInstance(), credentialsService.getUsuarioLogado());
						notesDialog.dismiss();
					}
					if (processo.equals(ProcessoItem.CANCELAR)){
						getInstance().setMotivoCancelamento(notasFinalizacao.getText().toString());
						atividadeService.cancelar(getInstance(), credentialsService.getUsuarioLogado());
						notesDialog.dismiss();
					}
					if (processo.equals(ProcessoItem.ADIAR)){
						if(!cancelado){
							atividadeService.adiar(getInstance()
														, credentialsService.getUsuarioLogado()
														, dataAdiamento.getTime()
														, horaAdiamento.getTime());
						}
					}
//					if (processo.equals(ProcessoItem.RENOVAR)){
//						atividadeService.renovar(getInstance(), credentialsService.getUsuarioLogado());
//					}
				}
				pesquisar(grupo);
				break;
			case DialogInterface.BUTTON_NEGATIVE:
				alertYesNo.dismiss();
				break;
			}			
		}
	};
	
	DatePickerDialog.OnDateSetListener onDateListener = new DatePickerDialog.OnDateSetListener() {
		
		@Override
		public void onDateSet(DatePicker arg0, int year, int month, int day) {
			dataAdiamento = Calendar.getInstance();
			dataAdiamento.set(Calendar.DATE, day);
			dataAdiamento.set(Calendar.MONTH, month);
			dataAdiamento.set(Calendar.YEAR, year);
			dataAdiamento.set(Calendar.HOUR, 0);
			dataAdiamento.set(Calendar.MINUTE, 0);
			dataAdiamento.set(Calendar.SECOND, 0);
			if (!cancelado){
				if (postponeTimePicker == null || !postponeTimePicker.isShowing()){
					if (!util.date1IsHigherOrEqualThanDate2(dataAdiamento.getTime(), util.getCurrentDate().getTime())){
						util.showToastMessageLong(getString(R.string.msg_validate_date_postpone), AdministratorListActivity.this);
						return;
					}
					Calendar calendar = Calendar.getInstance();
					calendar.setTime(new Date());
					calendar.add(Calendar.MINUTE, 10);
					String titulo = getString(R.string.current_time_title);
					if (getInstance().getHoraAviso() != null 
							&& (util.date1IsHigherOrEqualThanDate2(new Date(), getInstance().getDataAviso()) 
							&& util.time1IsHigherThanTime2(getInstance().getHoraAviso(), new Date()))){
						calendar.setTime(getInstance().getHoraAviso());
						titulo = getString(R.string.current_alert_time_title);
					}
					postponeTimePicker = new TimePickerDialog(AdministratorListActivity.this
							, onTime
							, calendar.get(Calendar.HOUR_OF_DAY)
							, calendar.get(Calendar.MINUTE)
							, true);
					
					postponeTimePicker.setButton(DatePickerDialog.BUTTON_NEGATIVE, getString(R.string.cancel), cancelClick);
					postponeTimePicker.setMessage(titulo);
					postponeTimePicker.setCanceledOnTouchOutside(false);
					postponeTimePicker.show();
				}
			}
		}
	};
	
	DialogInterface.OnClickListener cancelClick = new DialogInterface.OnClickListener() {
		@Override
		public void onClick(DialogInterface arg0, int arg1) {
			cancelado = true;
		}
	};

	
	TimePickerDialog.OnTimeSetListener onTime = new TimePickerDialog.OnTimeSetListener() {
			
		@Override
		public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
			if (!cancelado){
				horaAdiamento = Calendar.getInstance();
				horaAdiamento.set(Calendar.HOUR_OF_DAY, hourOfDay);
				horaAdiamento.set(Calendar.MINUTE, minute);
				horaAdiamento.set(Calendar.SECOND, 0);
				if (util.date1IsEqualThanDate2(dataAdiamento.getTime(), util.getCurrentDate().getTime())
						&& (horaAdiamento.getTime().before(util.getCurrentTime()) || horaAdiamento.getTime().equals(util.getCurrentTime()))){
					util.showToastMessageLong(getString(R.string.msg_validate_time_postpone), AdministratorListActivity.this);
					return;
				}
				String param = util.dateToString(dataAdiamento.getTime())+", "+util.timeToString(horaAdiamento.getTime());
				alertYesNo.setMessage(getString(R.string.msg_postpone_appointment, param));
				alertYesNo.show();
			}
		}
	};
	

	AdapterView.OnItemLongClickListener onLongClick = new AdapterView.OnItemLongClickListener() {
		
		@Override
		public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
			int itemType = ExpandableListView.getPackedPositionType(id);
			if ( itemType == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {
	        	int childPosition = ExpandableListView.getPackedPositionChild(id);
	            int groupPosition = ExpandableListView.getPackedPositionGroup(id);
	  			setInstance((Atividade)admListener.getChild(groupPosition, childPosition));
	  			if (getInstance() != null && getInstance().getCodigo() != null){
	  				Dialog dialog = atividadeService.criarPopupAdm(view, getInstance());
	  				dialog.show();
	  				return true;
	  			}
			 }
			return false;
		}

	};
	
	OnClickListener onClickConcluidas = new OnClickListener() {
		
		@Override
		public void onClick(DialogInterface dialog, int which) {
			switch (which) {
			case 0:
				loadInstance(AppointmentActivity.class, atividadeService.getColumnHack(), getInstance().getCodigo(), false, R.layout.activity_administrator_list);
				break;
			case 1:
				duplicate(AppointmentActivity.class, atividadeService.getColumnHack(), getInstance().getCodigo(), R.layout.activity_administrator_list);
				break;
			case 2:
				if (getInstance() != null && getInstance().getCodigo() != null){
					processo = ProcessoItem.EXCLUIR;
					alertYesNo.setMessage(getString(R.string.remove_appointment_message, getInstance().getTitulo()));
					alertYesNo.show();
				}
				break;
			}
		}
	};
	
	
	public void searchAdm(View v) {
		openView(AdministratorListActivity.this, SearchAdmActivity.class, false);
	}
	
	public void onClickOpenPopupAdm(View v) {
		Object groupIndex = v.getTag(R.id.TAG_GROUP_POSITION);
		Object childIndex = v.getTag(R.id.TAG_CHILD_POSITION);
		if (groupIndex != null && childIndex != null && groupIndex instanceof Integer && childIndex instanceof Integer){
			int newGroupIndex = (Integer)groupIndex;
			int newChildIndex = (Integer)childIndex;
			setInstance((Atividade)admListener.getChild(newGroupIndex, newChildIndex));
			Dialog dialog = atividadeService.criarPopupAdm(v, getInstance());
			dialog.show();
		}
	}
	
}
